package cn.memset.code.lambda;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class MethodReferenceExample {
    public static void main(String[] args) {
        ctorMethodReference();
    }

    public static void simpleMethodReference() {
        Map<String, Integer> wordMap = new HashMap<>();
        wordMap.computeIfAbsent("hello", String::length);
        System.out.println(wordMap);
    }

    public static void objectInstanceMethodReference() {
        String me = "me";

        // wordMap 的 key 是给定的单词，value是不区分大小写，与单词 "me" 比较后得出的值
        Map<String, Integer> wordMap = new HashMap<>();

        // me::compareToIgnoreCase 等价于 s ->  me.compareToIgnoreCase(s)
        wordMap.computeIfAbsent("him", me::compareToIgnoreCase);
        wordMap.computeIfAbsent("you", s -> me.compareToIgnoreCase(s));

        System.out.println(wordMap);
    }

    public static void classStaticMethodReference() {
        List<String> list = Arrays.asList("Guangdong", "Zhejiang", "Jiangsu");

        // System.out::println 等价于 s -> System.out.println(s)
        list.forEach(System.out::println);
    }

    public static void classInstanceMethodReference() {
        Map<String, Integer> wordMap = new HashMap<>();
        Integer wordLen = wordMap.computeIfAbsent("hello", String::length);
        System.out.println(wordMap);
    }

    public static void ctorMethodReference() {
        List<String> list = Arrays.asList("1.1", "2.2", "3.3");

        // BigDecimal::new 根据上下文推断，等价于 s -> new BigDecimal(s)
        Stream<BigDecimal> stream = list.stream().map(BigDecimal::new);
        List<BigDecimal> decimalList = stream.collect(Collectors.toList());
        System.out.println(decimalList);

        // 构建一个新的 Stream ，之前的 Stream 已经被关闭了
        Stream<BigDecimal> stream1 = list.stream().map(BigDecimal::new);

        // BigDecimal[]::new ，数组的构造器引用，等价于 x -> new BigDecimal[x]
        BigDecimal[] decimalArray = stream1.toArray(BigDecimal[]::new);
        for (BigDecimal d : decimalArray) {
            System.out.println(d);
        }
    }
}
